package main

import "fmt"

// ---- 抽象层-----
// 抽象的观察者
type Listener interface {
	OnTeacherComming() // 观察者得到通知后要触发具体的动作
}

type Notifier interface {
	AddListener(listener Listener)
	RemoveListener(Listener Listener)
	Notify()
}

// -----实现层-----
// 观察者具体的学生
type StuZhang3 struct {
	Badthing string
}

func (s *StuZhang3) DoBadthing() {
	fmt.Println("张三 正在", s.Badthing)
}

func (s *StuZhang3) OnTeacherComming() {
	fmt.Println("张三 停止", s.Badthing)
}

type StuZhao4 struct {
	Badthing string
}

func (sz *StuZhao4) DoBadthing() {
	fmt.Println("张三 正在", sz.Badthing)
}

func (sz *StuZhao4) OnTeacherComming() {
	fmt.Println("赵四 停止", sz.Badthing)
}

type StuWang5 struct {
	Badthing string
}

func (w *StuWang5) DoBadthing() {
	fmt.Println("张三 正在", w.Badthing)
}

func (w *StuWang5) OnTeacherComming() {
	fmt.Println("王5 停止", w.Badthing)
}

// 统治者班长

type ClassMonitor struct {
	listenerList []Listener // 需要通知的全部观察者合集
}

func (m *ClassMonitor) AddListener(listener Listener) {
	m.listenerList = append(m.listenerList, listener)
}

func (m *ClassMonitor) RemoveListener(listener Listener) {
	for index, l := range m.listenerList {
		// 找到要删除的元素位置
		if listener == l {
			// 将删除的元素的前后位置链接起来
			m.listenerList = append(m.listenerList[:index], m.listenerList[index+1:]...)
			break
		}
	}
}

func (m *ClassMonitor) Notify() {
	for _, listener := range m.listenerList {
		listener.OnTeacherComming() //多态现象
	}
}

// 业务逻辑
func main() {
	s1 := &StuZhang3{
		Badthing: "抄作业",
	}

	s2 := &StuZhao4{
		Badthing: "玩王者荣耀",
	}

	s3 := &StuWang5{
		Badthing: "看赵4玩王者荣耀",
	}

	ClassMonitor := new(ClassMonitor)
	ClassMonitor.AddListener(s1)
	ClassMonitor.AddListener(s2)
	ClassMonitor.AddListener(s3)

	fmt.Println("上课了  但是老师还没来,学生们在忙自己的事情...")
	s1.DoBadthing()
	s2.DoBadthing()
	s3.DoBadthing()

	fmt.Println("这时候老师来了,班长给同学们使了个眼神..")
	ClassMonitor.Notify()

}
